// Windows/Time.cpp

#include "StdAfx.h"

#include "Defs.h"

#include "Time.h"

namespace Common{
namespace System {
namespace Time {

static const UINT32 kNumTimeQuantumsInSecond = 10000000;
static const UINT32 kFileTimeStartYear = 1601;
static const UINT32 kUnixTimeStartYear = 1970;
static const UINT64 kUnixTimeStartValue = ((UINT64)kNumTimeQuantumsInSecond) *
    60 * 60 * 24 * (89 + 365 * (kUnixTimeStartYear - kFileTimeStartYear));

static const UINT32 kHighDosTime = 0xFF9FBF7D;
static const UINT32 kLowDosTime = 0x210000;

bool FileTimeToDosTime(const FILETIME &ft, UINT32 &dosTime)
{
  WORD datePart, timePart;
  if (!::FileTimeToDosDateTime(&ft, &datePart, &timePart))
  {
    dosTime = (ft.dwHighDateTime >= 0x01C00000) ? kHighDosTime : kLowDosTime;
    return false;
  }
  dosTime = (((UINT32)datePart) << 16) + timePart;

  return true;
}

bool FileTimeToUnixTime(const FILETIME &ft, UINT32 &unixTime)
{
  UINT64 winTime = (((UINT64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
  if (winTime < kUnixTimeStartValue)
  {
    unixTime = 0;
    return false;
  }
  winTime = (winTime - kUnixTimeStartValue) / kNumTimeQuantumsInSecond;
  if (winTime > 0xFFFFFFFF)
  {
    unixTime = 0xFFFFFFFF;
    return false;
  }
  unixTime = (UINT32)winTime;
  return true;
}

void GetCurUtcFileTime(FILETIME &ft)
{
  SYSTEMTIME st;
  GetSystemTime(&st);
  SystemTimeToFileTime(&st, &ft);
}

}} }
